from math import sqrt, exp
from pathCreator import PathCreator
from random import seed

class Montecarlo:
    def __init__(self, contract, marketData):
        self.contract = contract
        self.marketData = marketData

    def quote(self, numPaths, s):
        """Evaluates the option with Black-Scholes model using Monte Carlo and returns the discounted expected value"""
        seed(s)
        paths = []
        s_z = self.marketData.price
        r = self.marketData.rate
        v = self.marketData.volatility
        t = self.contract.expiry
        fixingDays = self.contract.fixingDays

        pathCreator = PathCreator(s_z, fixingDays, r, v, self.contract.base)
        
        for _ in range (0, numPaths):
            paths.append(self.contract.thePayoff(pathCreator.get_one_path()))

        mean = sum(paths) / numPaths
        value = exp(-r*t) * mean

        stdev = sqrt(sum(list(pow(v - mean, 2) for v in paths)) / (numPaths-1))
        ci = stdev * 1.96 / sqrt(numPaths)        
        return ({'value': value, 'ci': ci, 'numPaths' : numPaths})

    def __repr__(self):
        return "<Montecarlo %s %s>" % (self.contract, self.marketData)
